package com.jds.clickhouse.web.service.impl.sys;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jds.link4sales.model.entity.sys.SysMenu;
import com.jds.link4sales.model.mapper.sys.SysMenuMapper;
import com.jds.clickhouse.web.service.sys.SysMenuService;
import com.jds.clickhouse.web.service.sys.SysRoleMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <p>
 * sys_menu  服务实现类
 * </p>
 *
 * @author zhixiang.peng
 * @since 2020-11-03
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public List<SysMenu> selectMenuTreeByUserCode(String userCode) {

        List<SysMenu> menus = null;
        menus = sysMenuMapper.selectMenuTreeByUserCode(userCode);
        return getChildPerms(menus, 0);
    }

    @Override
    public List<SysMenu> selectAllMenuTree() {
        List<SysMenu> menus = null;
        menus = sysMenuMapper.selectAllMenuTree();
        return getChildPerms(menus, 0);
    }

    @Override
    public List<SysMenu> selectMenuByUserCode(String userCode) {
        return sysMenuMapper.selectMenuTreeByUserCode(userCode);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public void addFunction(SysMenu sysMenu) {
        //插入功能
        sysMenuMapper.insert(sysMenu);
        //更新节点
        List<SysMenu> sysMenuList = sysMenu.getChildren();
        sysMenuList.forEach(item -> {
            item.setParentId(sysMenu.getId());
        });
        this.saveOrUpdateBatch(sysMenuList);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public void updateFunction(SysMenu sysMenu) {
        sysMenuMapper.updateById(sysMenu);
        //原有节点置空
        this.update(new UpdateWrapper<SysMenu>().eq("parent_id",sysMenu.getId()).set("parent_id",null));
        //更新节点
        List<SysMenu> sysMenuList = sysMenu.getChildren();
        sysMenuList.forEach(item -> {
            item.setParentId(sysMenu.getId());
        });

        this.saveOrUpdateBatch(sysMenuList);
    }

    @Override
    public List<Integer> selectDataAuthByUrlAndUserCode(String url,String userCode) {
        return sysMenuMapper.selectDataAuthByUrlAndUserCode(url,userCode);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public void setDataAuth(List<SysMenu> sysMenuList) {

        if(!CollectionUtils.isEmpty(sysMenuList)){
            sysMenuList.forEach(item->{
                Assert.notNull(item.getId(), " id不能为空");
                Assert.notNull(item.getDataAuthType(), " 权限类型不能为空");
                this.update(new UpdateWrapper<SysMenu>().eq("id",item.getId()).set("data_auth_type",item.getDataAuthType()));
            });
        }else {
            throw  new IllegalArgumentException("请求的参数为空");
        }
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
        List<SysMenu> returnList = new ArrayList<SysMenu>();
        for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext(); ) {
            SysMenu t = (SysMenu) iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenu> list, SysMenu t) {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        Iterator<SysMenu> it = list.iterator();
        while (it.hasNext()) {
            SysMenu n = (SysMenu) it.next();
            if (n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenu> list, SysMenu t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }


}
